<template>
  <div class="travel_price">
    <div class="base_details_title">基本信息</div>
    <div class="base_details_content_second">
      <el-form
        ref="baseDataFormRef"
        :model="baseData"
        :rules="basicRules"
        label-width="100px"
        class="base_details_form"
        :disabled="readOnly"
      >
        <el-form-item label="房型名称" prop="roomName">
          <el-input v-model="baseData.roomName" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="房间封面" prop="roomPic">
          <UploadSinglePicture
            v-model="baseData.roomPic"
            :disabled="readOnly"
            :width="120"
          />
        </el-form-item>
        <el-form-item label="可住人数" prop="peopleNum">
          <el-input-number v-model="baseData.peopleNum" :min="1" :max="50" />
        </el-form-item>
        <el-form-item label="是否有窗" prop="windowConfig">
          <el-radio-group v-model="baseData.windowConfig">
            <el-radio
              v-for="item in windowOptions"
              :key="item.id"
              :label="item.value"
            >
              {{ item.label }}</el-radio
            >
          </el-radio-group>
        </el-form-item>
        <el-form-item label="床型说明" prop="bedIntro">
          <el-input
            v-model="baseData.bedIntro"
            :rows="3"
            type="textarea"
            resize="none"
          />
        </el-form-item>
        <el-form-item label="是否含早" prop="breakfastConfig">
          <el-radio-group v-model="baseData.breakfastConfig">
            <el-radio
              v-for="item in breakfastOptions"
              :key="item.id"
              :label="item.value"
            >
              {{ item.label }}</el-radio
            >
          </el-radio-group>
        </el-form-item>
        <el-form-item label="能否取消" prop="cancelConfig">
          <el-radio-group v-model="baseData.cancelConfig">
            <el-radio
              v-for="item in cancelOptions"
              :key="item.id"
              :label="item.value"
            >
              {{ item.label }}</el-radio
            >
          </el-radio-group>
        </el-form-item>
        <el-form-item label="房间设施" prop="facility">
          <el-checkbox-group v-model="baseData.facility">
            <el-checkbox
              v-for="(item, index) in roomConfigure"
              :key="index"
              :label="item.value"
            >
              {{ item.label }}</el-checkbox
            >
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="房型说明" prop="roomIntro">
          <el-input
            v-model="baseData.roomIntro"
            :rows="3"
            type="textarea"
            resize="none"
          />
        </el-form-item>
      </el-form>
    </div>
    <div class="base_details_title">日期价格设置</div>
    <div class="base_details_content_second">
      <HotelPriceOperate
        ref="priceOperateRef"
        @execute="execute"
        @checkOperateChange="checkOperateChange"
        @calendarSwitch="calendarSwitch"
      />
      <PriceCalendar
        ref="calendarRef"
        :number="calendarNumber"
        @select="calendarSelect"
        @del="calendarDel"
      />
      <div id="scrollPoint"></div>
      <el-table-v2
        ref="tableRef"
        :columns="hotelPriceColumns"
        :data="hotelPriceDate"
        :width="850"
        :height="700"
      >
        <template #empty> </template>
      </el-table-v2>
    </div>
  </div>
</template>
<script setup>
import { ref, reactive, nextTick, defineExpose } from "vue";
import HotelPriceOperate from "./HotelPriceOperate.vue";
import PriceCalendar from "@/components/travel/setMeal/PriceCalendar.vue";
import msg from "@ui/message";
import UploadSinglePicture from "@com/upload/UploadSinglePicture.vue";
import api from "@api/hotel";
import $ from "@util/base";

const windowOptions = ref([]);
const breakfastOptions = ref([]);
const cancelOptions = ref([]);
const roomConfigure = ref([]);

const readOnly = ref(false);
const tableRef = ref(null);
const baseDataFormRef = ref(null);
const baseData = reactive({
  roomName: null,
  roomPic: null,
  peopleNum: 1,
  windowConfig: null,
  bedIntro: null,
  breakfastConfig: null,
  cancelConfig: null,
  facility: [],
  roomIntro: null,
  roomPriceDateItems: [],
});
const basicRules = {
  roomName: [
    {
      required: true,
      message: "请输入套餐名称",
      trigger: "blur",
    },
  ],
  roomPic: [
    {
      required: true,
      message: "请上传房间封面",
      trigger: "blur",
    },
  ],
  windowConfig: [
    {
      required: true,
      message: "请选择窗户情况",
      trigger: "blur",
    },
  ],
};

getConfig();
function getConfig() {
  api.windowConfig((val) => (windowOptions.value = val));
  api.breakfastConfig((val) => (breakfastOptions.value = val));
  api.cancelConfig((val) => (cancelOptions.value = val));
  api.roomConfigure((val) => (roomConfigure.value = val));
}

const calendarNumber = ref(localStorage.getItem("calendarNumber") || 6);

const priceOperateRef = ref(null);
const calendarRef = ref(null);
var hotelPriceDate = ref([]);

const hotelPriceColumns = [
  {
    key: "priceDate",
    dataKey: "priceDate",
    title: "日期",
    width: 140,
  },
  {
    key: "stockNum",
    dataKey: "stockNum",
    title: "库存",
    width: 120,
    cellRenderer: (data) => (
      <el-input type="number" v-model={data.rowData.stockNum} />
    ),
  },
  {
    key: "costPrice",
    dataKey: "costPrice",
    title: "成本价(元)",
    width: 120,
    cellRenderer: (data) => (
      <el-input type="number" v-model={data.rowData.costPrice} />
    ),
  },
  {
    key: "competitorPrice",
    dataKey: "competitorPrice",
    title: "同行价(元)",
    width: 120,
    cellRenderer: (data) => (
      <el-input type="number" v-model={data.rowData.competitorPrice} />
    ),
  },
  {
    key: "sellPrice",
    dataKey: "sellPrice",
    title: "销售价(元)",
    width: 120,
    cellRenderer: (data) => (
      <el-input type="number" v-model={data.rowData.sellPrice} />
    ),
  },
  {
    key: "markingPrice",
    dataKey: "markingPrice",
    title: "划线价(元)",
    width: 120,
    cellRenderer: (data) => (
      <el-input type="number" v-model={data.rowData.markingPrice} />
    ),
  },
  {
    key: "del",
    dataKey: "del",
    title: "操作",
    width: 100,
    cellRenderer: (data) => (
      <el-button
        type="danger"
        onClick={priceDelete.bind(this, data.rowData, data.rowIndex)}
      >
        删除
      </el-button>
    ),
  },
];

function calendarSwitch(val) {
  if (val) {
    calendarNumber.value = 6;
    localStorage.setItem("calendarNumber", 6);
  } else {
    calendarNumber.value = 12;
    localStorage.setItem("calendarNumber", 12);
  }
  loadCalendar();
}

function formatDate(date) {
  return (
    date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate()
  );
}

function insertTemplate(date, source, template) {
  for (let index = 0; index < template.length; index++) {
    const element = template[index];
    let data = {
      priceDate: formatDate(date),
      dateSrc: date,
    };
    for (const key in element) {
      data[key] = element[key];
    }
    source.push(data);
  }
}

/**
 *  添加日期价格
 * 1、检查与原数据日期是否冲突
 * 2、添加数据
 * 3、排序
 */
function addHotelDate(isDuringCheck, startDate, endDate, week, templateData) {
  if (isDuringCheck) {
    //判断新增日期是否和已编辑日期冲突
    if (isDuringDate(startDate, endDate, week)) {
      msg.error("添加日期价格于现有日期价格冲突");
      return false;
    }
  }

  var prevDate = startDate;
  var dateData = [];

  if (isMeetWeek(startDate, week)) {
    insertTemplate(startDate, dateData, templateData);
  }

  //构建日期区间
  const day = diffDay(startDate, endDate);
  for (let index = 0; index < day; index++) {
    prevDate = nextDay(prevDate);
    if (isMeetWeek(prevDate, week)) {
      insertTemplate(prevDate, dateData, templateData);
    }
  }

  //日期合并
  if (hotelPriceDate.value.length <= 0) {
    hotelPriceDate.value = hotelPriceDate.value.concat(dateData);
  } else {
    hotelPriceDate.value = hotelPriceDate.value.concat(dateData);
    //排序
    hotelPriceDate.value.sort((a, b) => {
      return a.dateSrc - b.dateSrc;
    });
  }
  return true;
}

/**
 * 覆盖日期价格
 * 1、原数据中删除需要覆盖的日期
 * 2、添加数据
 * 3、排序
 */
function coverTravelDate(startDate, endDate, week, templateData) {
  for (var i = hotelPriceDate.value.length - 1; i >= 0; i--) {
    let oldDate = hotelPriceDate.value[i];
    if (
      isMeetWeek(oldDate.dateSrc, week) &&
      oldDate.dateSrc >= startDate &&
      oldDate.dateSrc <= endDate
    ) {
      hotelPriceDate.value.splice(i, 1);
    }
  }
  addHotelDate(false, startDate, endDate, week, templateData);
}

function loadCalendar() {
  nextTick(() => {
    calendarRef.value.setChecked(hotelPriceDate.value);
  });
}

function isMeetWeek(date, week) {
  return week.includes(date.getDay());
}

function isDuringDate(startDate, endDate, week) {
  for (const oldDate of hotelPriceDate.value) {
    if (!isMeetWeek(oldDate.dateSrc, week)) {
      continue;
    }
    if (oldDate.dateSrc >= startDate && oldDate.dateSrc <= endDate) {
      return true;
    }
  }
  return false;
}

function diffDay(date_1, date_2) {
  let totalDays, diffDate;
  diffDate = Math.abs(date_1 - date_2);
  totalDays = Math.floor(diffDate / (1000 * 3600 * 24));
  return totalDays;
}

function nextDay(date) {
  date = new Date(date);
  date = +date + 1000 * 60 * 60 * 24;
  date = new Date(date);
  return date;
}

function priceDelete(date, index) {
  hotelPriceDate.value.splice(index, 1);
  calendarRef.value.setChecked(hotelPriceDate.value);
}

function checkOperateChange(callback) {
  if (hotelPriceDate.value.length <= 0) {
    return callback(true);
  } else {
    return callback(false);
  }
}

function calendarDel(data) {
  for (let index = 0; index < hotelPriceDate.value.length; index++) {
    const element = hotelPriceDate.value[index];
    if (
      data.year == element.dateSrc.getFullYear() &&
      data.month == element.dateSrc.getMonth() + 1 &&
      data.day == element.dateSrc.getDate()
    ) {
      hotelPriceDate.value.splice(index, 1);
      break;
    }
  }
}

function calendarSelect(data, callback) {
  const date = new Date(data.year, data.month - 1, data.day);
  if (data.checked) {
    document.getElementById("scrollPoint").scrollIntoView();
    jumpTableDate(date);
    callback(false);
  } else {
    if (priceOperateRef.value.validate()) {
      callback(insertTableDate(date));
    } else {
      callback(false);
    }
  }
}

function jumpTableDate(date) {
  for (let index = 0; index < hotelPriceDate.value.length; index++) {
    const element = hotelPriceDate.value[index];
    if (
      date.getFullYear() == element.dateSrc.getFullYear() &&
      date.getMonth() == element.dateSrc.getMonth() &&
      date.getDate() == element.dateSrc.getDate()
    ) {
      tableRef.value.scrollToRow(index, "start");
      break;
    }
  }
}

function insertTableDate(date) {
  const template = priceOperateRef.value.getOperate().template;
  var isExist = false;
  for (const price of hotelPriceDate.value) {
    if (
      date.getFullYear() == price.dateSrc.getFullYear() &&
      date.getMonth() == price.dateSrc.getMonth() &&
      date.getDate() == price.dateSrc.getDate()
    ) {
      isExist = true;
    }
  }
  if (!isExist) {
    insertTemplate(date, hotelPriceDate.value, template);
    console.log(hotelPriceDate.value);
    hotelPriceDate.value.sort((a, b) => {
      return a.dateSrc - b.dateSrc;
    });
    return true;
  }
  return false;
}

function execute(data) {
  if (data.operate == "clear") {
    hotelPriceDate.value = [];
    loadCalendar();
  } else if (data.operate == "modify") {
    let startDate = new Date(data.date[0]);
    let endDate = new Date(data.date[1]);
    coverTravelDate(startDate, endDate, data.week, data.template);
    loadCalendar();
  } else if (data.operate == "add") {
    let startDate = new Date(data.date[0]);
    let endDate = new Date(data.date[1]);
    if (addHotelDate(true, startDate, endDate, data.week, data.template)) {
      loadCalendar();
    }
  }
}

function improtHotelDate(data) {
  const nowDate = new Date(new Date().setHours(0, 0, 0, 0));
  var travelData = [];
  for (const e of data) {
    var handleData = {};
    handleData.dateSrc = new Date(e.priceDate);
    if (handleData.dateSrc < nowDate) {
      continue;
    }
    for (const key in e) {
      if (key != "dateSrc") {
        handleData[key] = e[key];
      }
    }
    travelData.push(handleData);
  }
  hotelPriceDate.value = travelData;
}

function improtData(data) {
  baseData.id = data.id;
  baseData.roomCode = data.roomCode;
  baseData.roomName = data.roomName;
  baseData.roomPic = data.roomPic;
  baseData.peopleNum = data.peopleNum;
  baseData.windowConfig = data.windowConfig;
  baseData.bedIntro = data.bedIntro;
  baseData.breakfastConfig = data.breakfastConfig;
  baseData.cancelConfig = data.cancelConfig;

  baseData.roomIntro = data.roomIntro;
  if ($.isNotEmpty(data.facility)) {
    baseData.facility = data.facility.split(",").map((e) => {
      return parseInt(e);
    });
  } else {
    baseData.facility = [];
  }
  // priceOperateRef.value.importData(data.packagePriceItems);
  improtHotelDate(data.roomPriceDateItems);
  loadCalendar();
}

function reset() {
  baseDataFormRef.value.resetFields();
  priceOperateRef.value.resetData();
  hotelPriceDate.value = [];
  loadCalendar();
}

function save(callback) {
  baseDataFormRef.value.validate((valid) => {
    if (valid) {
      if (hotelPriceDate.value.length > 0) {
        var data = {};

        for (const key in baseData) {
          data[key] = baseData[key];
        }

        if ($.isNotEmpty(baseData.facility)) {
          data.facility = baseData.facility.join(",");
        } else {
          data.facility = null;
        }
        // let operateData = priceOperateRef.value.getData();
        // data.packagePriceItems = operateData.price;
        data.roomPriceDateItems = hotelPriceDate.value;
        callback(data);
      } else {
        callback(false);
        msg.error("请设置日期价格");
      }
    } else {
      callback(false);
    }
  });
}

defineExpose({ improtData, reset, save });
</script>

<style lang="scss" scoped>
.travel_price {
  .base_details_title {
    margin: 5px 0;
  }

  .base_details_content_second {
    margin-bottom: 0;
  }
}
</style>